#pragma once
#include <zCoreConfig.hpp>
#include "../common.hpp"
#include "Timer.hpp"

// Mimic Google progress bar behavior

namespace zzz {
#define ZVERBOSE_PROGRESS_BAR (ZINFO)
class ZCORE_CLASS TextProgressBar {
public:
  typedef enum {STYLE_NORMAL, STYLE_Z} Style;
  TextProgressBar(const string &msg, bool active_mode = false, Style style = STYLE_Z);
  void SetActiveMode(bool mode);
  void SetMaximum(int x);
  void SetMinimum(int x);
  void SetValue(int x);
  void SetDelayStart(double sec);
  void SetNormalChar(char blank, char fill);
  void SetZChar(const string &zstyle_char);
  void SetUpdateRate(double rate);
  void Start();
  void End(bool clear = false);
  void Update(int value);
  void DeltaUpdate(int value_delta=1);
  void Pulse();
private:
  bool CheckDelayStart();
  void Show(bool end);
  void ShowActive(bool end);
  void Clear();
  string SecondsToTime(double sec);
  Style style_;
  bool active_mode_;
  int console_width_;
  
  // for bar
  string msg_;
  string bar_;
  int max_, min_, value_;
  int bar_length_;
  // for non-zstyle
  char blank_, fill_;
  int running_char_count_;
  // for zstyle
  string zstyle_char_;
  zuint next_update_;
  vector<int> bar_char_count_;
  vector<int> update_order_;

  int actbar_length_;
  int actbar_pos_;

  int percentage_;

  Timer timer_, last_timer_;
  int last_timer_count_;
  double update_rate_;
  double delay_start_;

  bool started_;
};

class ScopeTextProgressBar : public TextProgressBar {
public:
  ScopeTextProgressBar(const string& msg, int minv, int maxv, double delay_start = 0)
      : TextProgressBar(msg) {
    SetMinimum(minv);
    SetMaximum(maxv);
    SetDelayStart(delay_start);
    Start();
  }
  ~ScopeTextProgressBar() {
    End();
  }
};
}  // namespace zzz